<?php

if(!defined('EXECROOT')) {
	define('EXECROOT','');
}

/*//.

	//. required
	id = *unique* button id

	//. optional
	text = text to have on button
	alive = mouse sensisive (boolean)
	hard = break the red alert state break (boolean)
	c1 = normal colour (hex string)
	c2 = hover colour
	c3 = active colour
	c4 = attention colour
	tc = text colour
	ta = text align
	tx = x position of text
	ty = y position of text
	ts = text size in points (i think points)
	tr = text rotation
	h = height of object (block buttons only)
	w = width of object (block buttons only)
	snd (flag)
	
.//*/

class lcarsButton extends GtkFixed {

	const TYPE_RIGHT = '/usr/share/commnet/ui/lcars-btn-01.png';
	const TYPE_LEFT = '/usr/share/commnet/ui/lcars-btn-02.png';
	const TYPE_BLOCK = '__BLOCK__';
	const STATE_HOVER = 1;
	const STATE_ACTIVE = 2;
	const STATE_ATTN = 4;
	const STATE_BLINK = 8;
	const RIGHT = 1;
	const TOP = 2;
	

	private $type;
	private $colourNormal,$colourHover,$colourActive,$colourAttn,$colourSpecial1,$colourSpecial2;
	private $width,$height;
	private $putx,$puty;
	private $mouseState;
	private $callbackClick;
	private $attrib;
	private $gdtx,$gdty,$gdts,$gdtr;
	private $blinkColour1,$blinkColour2,$blinkTimeout,$blinkState;

	private $ebox,$image;

	public function __construct($type,$attrib = null) {

		if(!is_array($attrib)) {
			die("custom should be array.");
		}

		if(!array_key_exists('id',$attrib)) {
			die("id is required.\n");		
		}

		$this->image = null;
		$this->attrib = $attrib;
		
		if(!array_key_exists('text',$this->attrib)) { $this->attrib['text'] = ''; }
		else { $this->attrib['text'] = strtoupper($this->attrib['text']); }

		if(!array_key_exists('snd',$this->attrib)) { $this->attrib['snd'] = lcars::SND_INIT_DEFAULT; }
		else { $this->attrib['snd'] = $attrib['snd']; }
		
		if(!array_key_exists('hard',$this->attrib)) { $this->attrib['hard'] = false; }
	
		$this->type = $type;
		$this->colourNormal = ((array_key_exists('c1',$this->attrib))?($this->attrib['c1']):('#8fc4fe'));
		$this->colourHover = ((array_key_exists('c2',$this->attrib))?($this->attrib['c2']):('#a5e5fe'));
		$this->colourActive = ((array_key_exists('c3',$this->attrib))?($this->attrib['c3']):('#ff8a00'));	
		$this->colourAttn = ((array_key_exists('c4',$this->attrib))?($this->attrib['c4']):('#ff0000'));
		
		$this->mouseState = 0;
		$this->callbackClick = null;

		parent::__construct();
		
		if($this->type != self::TYPE_BLOCK) {
			if($this->type == self::TYPE_RIGHT || $this->type == self::TYPE_LEFT) {
				$this->type = EXECROOT.$this->type;
			}
			
			list($this->width,$this->height) = getimagesize($this->type);
		} else {
			$this->width = $this->attrib['w'];
			$this->height = $this->attrib['h'];
		}
		
		
		$this->ebox = new GtkEventBox;
		//. setting states active/prelight was not working, so i've fallen
		//. back to using callbacks to modify normal.
		
		if(!array_key_exists('alive',$this->attrib) || $this->attrib['alive'] === true) {
			$this->ebox->add_events(Gdk::ENTER_NOTIFY_MASK|Gdk::LEAVE_NOTIFY_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK);
			$this->ebox->connect_simple('enter-notify-event',array($this,'onMouseOver'));
			$this->ebox->connect_simple('leave-notify-event',array($this,'onMouseOut'));
			$this->ebox->connect_simple('button-press-event',array($this,'onMouseDown'));
			$this->ebox->connect_simple('button-release-event',array($this,'onMouseUp'));
		}
		
		$this->ebox->set_size_request($this->width,$this->height);
		$this->ebox->modify_bg(Gtk::STATE_NORMAL,GdkColor::parse($this->colourNormal));
		$this->put($this->ebox,0,0);

		$this->generateImage();		

		$this->show_all();
		return;
	}
	
	public function onMouseOver() {
		if(lcars::$redAlert) { return; }
		$this->mouseState |= self::STATE_HOVER;
		$this->ebox->modify_bg(Gtk::STATE_NORMAL,GdkColor::parse($this->colourHover));
		return;
	}

	public function onMouseOut() {
		if(lcars::$redAlert) { return; }
		$this->mouseState |= self::STATE_HOVER;
		if($this->mouseState & self::STATE_ATTN) {
			$this->ebox->modify_bg(Gtk::STATE_NORMAL,GdkColor::parse($this->colourAttn));
		} else {
			$this->ebox->modify_bg(Gtk::STATE_NORMAL,GdkColor::parse($this->colourNormal));
		}
		return;
	}

	public function onMouseDown() {
		$this->setActive(true);
		
		if($snd = lcars::getArrayValue('snd',$this->attrib)) {
			lcars::mksnd($snd);
		}

		return;
	}

	public function onMouseUp() {
		$this->setActive(false);
		
		return;
	}
	
	public function generateImage($re = false) {
		
		if($re && !is_null($this->image)) {
			$this->ebox->remove($this->image);
			$this->image->destroy();
			$this->image = null;
		}
		
		$gdfile = sprintf('%s%s/%s.png',EXECROOT,lcars::UI_CACHE_DIR,lcars::mkUIFilename($this->attrib['id']));

		if($this->type == self::TYPE_BLOCK && !$this->attrib['text']) {
			if(file_exists($gdfile)) { unlink($gdfile); }
			return;
		}

		$this->gdtx = $this->gdty = 0;
		if(array_key_exists('ts',$this->attrib)) { $this->gdts = $this->attrib['ts']; }
		else { $this->gdts = 16; }	

		if(array_key_exists('tr',$this->attrib)) { $this->gdtr = $this->attrib['tr']; }
		else { $this->gdtr = 0; }
		
		switch($this->type) {
			case(self::TYPE_RIGHT): {
				$this->gdtx = 2;
				$this->gdty = $this->height - 2;
				break;
			}
			
			case(self::TYPE_LEFT): {
				$this->gdtx = 2;
				$this->gdty = $this->height - 2;
				$this->attrib['ta'] &= self::RIGHT;
				break;		
			}
			
			case(self::TYPE_BLOCK): {
				if(array_key_exists('tx',$this->attrib)) { $this->gdtx = $this->attrib['tx']; }
				if(array_key_exists('ty',$this->attrib)) { $this->gdty = $this->attrib['ty']; }
				if(array_key_exists('w',$this->attrib)) { $this->width = $this->attrib['w']; }
				if(array_key_exists('h',$this->attrib)) { $this->height = $this->attrib['h']; }
				$this->gdtx = 2;
				$this->gdty = $this->height - 2;
				break;		
			}

			default: {
				$this->gdtx = 2;
				$this->gdty = $this->height - 2;
				if(array_key_exists('tx',$this->attrib)) { $this->gdtx = $this->attrib['tx']; }
				if(array_key_exists('ty',$this->attrib)) { $this->gdty = $this->attrib['ty']; }
				break;
			}
		}

		if(
			$re ||
			lcars::$forceRegen ||
			(array_key_exists('force',$this->attrib) && $this->attrib['force']) ||
			!file_exists($gdfile)
		) {
		
			if($this->type != self::TYPE_BLOCK) {			
				$gd = imagecreatefrompng($this->type);
				imagesavealpha($gd,true);
			} else {
				$gd = imagecreatetruecolor($this->width,$this->height);
				imagesavealpha($gd,true);
				
				$clear = imagecolorallocatealpha($gd,0,0,0,127);
				imagefill($gd,0,0,$clear);
			}
			
			imagealphablending($gd,true);
			imageantialias($gd,true);
			
			if(array_key_exists('tc',$this->attrib)) {
				list($r,$g,$b) = explode(',',$this->attrib['tc']);
				$black = imagecolorallocate($gd,$r,$g,$b);
				unset($r,$g,$b);
			} else {
				$black = imagecolorallocate($gd,0,0,0);
			}
			if($this->attrib['text']) {
				if(array_key_exists('ta',$this->attrib) && ($this->attrib['ta'] & self::RIGHT)) {
					$box = imagettfbbox($this->gdts,$this->gdtr, EXECROOT.lcars::TTF,$this->attrib['text']);
					$this->gdtx = ($this->width - ($box[2] - $box[0])) - 2;
				}
	
				if(array_key_exists('ta',$this->attrib) && ($this->attrib['ta'] & self::TOP)) {
					$box = imagettfbbox($this->gdts,$this->gdtr, EXECROOT.lcars::TTF,$this->attrib['text']);
					$this->gdty = 2 + ($box[1] - $box[7]);
				}
		
				imagettftext($gd, $this->gdts,$this->gdtr, $this->gdtx,$this->gdty, $black, EXECROOT.lcars::TTF, $this->attrib['text']);
			}
			
			imagepng($gd,$gdfile);
			imagedestroy($gd);
		}
		
		$this->image = GtkImage::new_from_file($gdfile);
		$this->ebox->add($this->image);
		$this->show_all();
		return;
	}
	
	public function setAttn($bool) {
		if($bool && !($this->mouseState & self::STATE_ATTN)) {
			$this->mouseState += self::STATE_ATTN;
			if(!lcars::$redAlert) {
				$this->ebox->modify_bg(Gtk::STATE_NORMAL,GdkColor::parse($this->colourAttn));
			}
		} else if(!$bool && ($this->mouseState & self::STATE_ATTN)) {
			$this->mouseState -= self::STATE_ATTN;
			if(!lcars::$redAlert) {
				$this->ebox->modify_bg(
					Gtk::STATE_NORMAL,
					(($this->mouseState & self::STATE_HOVER)?
						(GdkColor::parse($this->colourHover)):
						(GdkColor::parse($this->colourNormal))
					)	
				);
			}
		}
	}

	public function setActive($bool) {
		if($bool) {
			if(!($this->mouseState & self::STATE_ACTIVE)) {
				$this->mouseState += self::STATE_ACTIVE;
			}

			if(!lcars::$redAlert) {
				$this->ebox->modify_bg(Gtk::STATE_NORMAL,GdkColor::parse($this->colourActive));
			} else {
				if(!$this->attrib['hard']) {
					$this->ebox->modify_bg(Gtk::STATE_NORMAL,GdkColor::parse('#ffffff'));
				}		
			}

		} else if(!$bool) {
			if($this->mouseState & self::STATE_ACTIVE) {
				$this->mouseState -= self::STATE_ACTIVE;
			}
			
			if(!lcars::$redAlert) {
				$this->ebox->modify_bg(
					Gtk::STATE_NORMAL,
					(($this->mouseState & self::STATE_HOVER)?
						(GdkColor::parse($this->colourHover)):
						(GdkColor::parse($this->colourNormal))
					)	
				);
			} else {
				if(!$this->attrib['hard']) {
					$this->ebox->modify_bg(Gtk::STATE_NORMAL,GdkColor::parse('#ff0000'));
				}
			}
		}
		
		lcars::killTime();
		return;
	}
	
	public function setText($text) {
		$this->attrib['text'] = strtoupper($text);
		$this->generateImage(true);
		return;
	}
	
	public function setSize($w,$h) {
		$this->attrib['w'] = $this->width = $w;
		$this->attrib['h'] = $this->height = $h;
		$this->ebox->set_size_request($w,$h);
		$this->generateImage(true);
		return;
	}	
	
	public function getSize() {
		return array($this->width,$this->height);
	}
	
	public function getPosition() {
		return array($this->putx,$this->puty);
	}
	
	public function setPosition($fixed,$x,$y,$move = false) {
		$this->putx = $x;
		$this->puty = $y;
		if($move) {
			$fixed->move($this,$x,$y);
		} else {
			$fixed->put($this,$x,$y);
		}
		return;
	}
	
	public function setColour($colour,$define = false) {
		if($colour === false) {
			$this->ebox->modify_bg(Gtk::STATE_NORMAL,GdkColor::parse($this->colourNormal));		
		} else {
			if($define) {
				$this->colourNormal = $colour;
			}
			$this->ebox->modify_bg(Gtk::STATE_NORMAL,GdkColor::parse($colour));
		}
		
		return;
	}
	
	public function setBlink($colour1,$colour2,$rate = 1500) {
		if(!$colour1 || !$colour2) {
			$this->setColour(false);
			if($this->mouseState & self::STATE_BLINK) {
				$this->mouseState |= self::STATE_BLINK;
			}
			
			if($this->blinkTimeout) {
				Gtk::timeout_remove($this->blinkTimeout);
				$this->blinkTimeout = null;
			}
		} else {
			if(!($this->mouseState & self::STATE_BLINK)) {
				$this->mouseState |= self::STATE_BLINK;
			}
			
			$this->blinkState = true;
			$this->blinkColour1 = $colour1;
			$this->blinkColour2 = $colour2;
			$this->runBlink();
			$this->blinkTimeout = Gtk::timeout_add($rate,array($this,'runBlink'));
		}
		return;
	}
	
	public function runBlink() {

		if($this->blinkState) {
			$this->setColour($this->blinkColour1);
		} else {
			$this->setColour($this->blinkColour2);
		}
		
		$this->blinkState = !$this->blinkState;
	
		return true;
	}

}

?>